package com.knight.listener;

import com.knight.EventHandlerPool;
import com.knight.exception.EventDateException;
import com.knight.handler.EventHandler;
import com.knight.message.EventDate;
import com.sun.org.slf4j.internal.Logger;
import com.sun.org.slf4j.internal.LoggerFactory;
import org.springframework.context.ApplicationListener;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public abstract class AbstractEventListener<E,T> implements ApplicationListener<EventDate> {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private EventHandlerPool eventHandlerPool;

    protected AbstractEventListener(EventHandlerPool eventHandlerPool) {
        this.eventHandlerPool = eventHandlerPool;
    }

    @Override
    public void onApplicationEvent(EventDate eventDate) {
        checkParam(eventDate);//校验消息数据
        List<EventHandler> eventHandlerList = getEventHandlerList((E)eventDate.getEventType());//获取事件处理器集合
        if(eventHandlerList.size() == 0) {
            return;
        }
        handleEventDate(eventHandlerList,eventDate);//对消息事件进行处理
    }

    /**
     * 处理事件，可扩展
     * @param eventHandlerList
     * @param eventDate
     */
    abstract void handleEventDate(List<EventHandler> eventHandlerList, EventDate eventDate);

    /**
     * 获取事件处理器集合，并且对处理器进行排序
     * @return
     */
    private List<EventHandler> getEventHandlerList(E eventType) {
        //根据消息类型，查出符合条件的eventHandler集合，按顺序执行
        Map<E, List<EventHandler>> map = eventHandlerPool.getEventHandlerListMap();
        List<EventHandler> eventHandlerList = map.get(eventType);
        if (eventHandlerList == null || eventHandlerList.size() == 0) {
            logger.warn("该事件类型" + eventType.toString() + "，暂无对于的事件处理器，请验证是否事件类型内容正确...");
            return new ArrayList<>();
        }
        return eventHandlerList.stream().sorted(new Comparator<EventHandler>() {
            @Override
            public int compare(EventHandler eventHandler1, EventHandler eventHandler2) {
                if(eventHandler1.getOrder() > eventHandler2.getOrder()) {
                    return 1;
                }
                if(eventHandler1.getOrder() == eventHandler2.getOrder()) {
                    return 0;
                }
                return -1;
            }
        }).collect(Collectors.toList());
    }

    /**
     * 校验消息数据
     * @param eventDate
     */
    private void checkParam(EventDate eventDate) {
        if(eventDate.getEventType() == null) {
            logger.error("消息类型eventType不能为空");
            throw new EventDateException("消息类型eventType不能为空");
        }
        if(eventDate.getDate() == null) {
            logger.error("消息实体数据不能为空");
            throw new EventDateException("消息实体数据不能为空");
        }
    }



}
